package com.Comparaisons;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedList;

import Fenetre.FenetrePrincipale;
import Fenetre.ProgressPanel;

import com.Graphe;
import com.Link;
import com.Modele;
import com.Node;
import com.DB.*;

public class Counter {

	private DBConnector db = null;
	private ArrayList<Modele> modeles = null;
	private PrintWriter pr = null;
	private int seuil = 0;

	private FenetrePrincipale fenetre = null;

	private Graphe graphe = new Graphe();

	public Counter(DBConnector db,ArrayList<Modele> modeles,int seuil,FenetrePrincipale f) {
		this.db = db;
		this.modeles = modeles;
		this.seuil = seuil;
		this.fenetre = f;

		try {
			pr = new PrintWriter(new FileWriter("test.txt"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public Counter(DBConnector db,ArrayList<Modele> modeles,int seuil) {
		this.db = db;
		this.modeles = modeles;
		this.seuil = seuil;
		this.fenetre = null;

		try {
			pr = new PrintWriter(new FileWriter("test.txt"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void compter(){

		for(Modele m : modeles){
			graphe.add(Node.newNode(m));
		}

		Thread[] threads = new Thread[modeles.size()];

		for(int i=0;i<modeles.size();++i){
			final int index = i;
			Thread th =new Thread(
					new Runnable(){
						public void run(){
							comparer(modeles.get(index));
						}
					});
			th.start();
			threads[i] = th;
		}

		for(int i=0;i< threads.length;++i){
			try {
				threads[i].join();
				if(fenetre != null)
					fenetre.setProgressValue(ProgressPanel.COMTAGE,(i*100)/threads.length);
				else
					System.out.print(" "+((i*100)/threads.length)+"% ");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		if(fenetre != null)
			fenetre.setProgressValue(ProgressPanel.COMTAGE,100);

	}

	public void comparer(Modele m1){
		pr.println("--------------------"+m1+"--------------------");
		pr.flush();
		Node node = Node.newNode(m1);
		for(Modele m2 : modeles){
			Link link = comparer(m1,m2);
			if(link != null)
				node.addLink(link);
		}
	}

	public Link comparer(Modele m1, Modele m2){

		LinkedList<ArbreComparaisons> comparaisons = creer_ordre(m1,m2); //créé les comparaison des fils

		boolean affiche = false;

		for(ArbreComparaisons c : comparaisons){
			if(!affiche){
				pr.println("\n"+m1+" /\\ "+m2);
				affiche = true;
			}
			pr.println(c.getNoeud()+" : "+c.getNoeud().getNb());
			for(ArbreComparaisons b : c.getBranches()){
				pr.println("  "+c.getNoeud()+" /\\ "+b.getNoeud()+" : "+b.getNoeud().getNb());
			}
			pr.flush();
		}

		if(comparaisons.size()>0){
			Link link = new Link(m1,m2);
			link.setComparaison(comparaisons);
			return link;
		}
		else
			return null;
	}

	public LinkedList<ArbreComparaisons> creer_ordre(Modele m1, Modele m2){

		DBCounter dbcounter = new DBCounter(db);

		LinkedList<ArbreComparaisons> comparaisons = new LinkedList<ArbreComparaisons>();

		int N1 = m1.getArite();
		int N2 = m2.getArite();

		for(int a=0;a<N1;++a){
			for(int b=0;b<N2;++b){

				Comparaison comparaison = new Comparaison(a, b);

				if(dbcounter.count(m1,m2,comparaison)>=seuil){
					ArbreComparaisons arbre = new ArbreComparaisons(comparaison);
					comparaisons.add(arbre);

					for(int c=0;c<N1;++c){
						for(int d=b+1;d<N2;++d){
							Comparaison comparaison2 = new Comparaison(c, d);
							if(dbcounter.count(m1,m2,comparaison,comparaison2)>=seuil)
								arbre.add(comparaison2);
						}
					}

					for(int c=a+1;c<N1;++c){
						for(int d=0;d<N2;++d){
							Comparaison comparaison2 = new Comparaison(c, d);
							if(!arbre.contient(comparaison2)){
								if(dbcounter.count(m1,m2,comparaison,comparaison2)>=seuil)
									arbre.add(comparaison2);
							}
						}
					}

				}

			}
		}

		return comparaisons;
	}

	public Graphe recupererGraphe(){
		return graphe;
	}

}
